home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
program
/
tjgold.zip
/
INSTALL.001
/
GOLDDB.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1995-07-12
|
74KB
|
2,449 lines
{--------------------------------------------------------------------------}
{ Product: TechnoJock's Turbo Toolkit }
{ Version: GOLD }
{ Build: 1.01 }
{ }
{ Copyright 1986-1995 TechnoJock Software, Inc. }
{ All Rights Reserved }
{ Restricted by License }
{--------------------------------------------------------------------------}
{**********************}
{** Unit: GOLDDB **}
{**********************}
{++++++++++++++++++++++++++++++} unit GOLDDB; {++++++++++++++++++++++++++++}
{$I GOLDFLAG.INC}
{$IFNDEF GOLDDB}
{$DEFINE GOLDDB}
{$ENDIF}
{++++++++++++++++++++++++++++++++} INTERFACE {+++++++++++++++++++++++++++++}
uses DOS, CRT, Goldwin, GoldHard, GoldMisc, GoldKey, GoldFast, DFBtree,
DFPage, GoldLink, DFBtreUT, GoldStr, GoldReal, GoldDate, GoldMemo,
GoldList;
const
EOH: byte = $0D;
EOFile: byte = $1A;
EOM: byte = $1A;
Space: byte = $20;
Astk: byte = $2A;
MaxRecLen = 4000;
MaxNdxLen = 245;
DFX = '.DBF'; { data file extension }
IFX = '.GDX'; { index file extension }
MFX = '.DBT'; { memo file extension }
MaxNdxStrLen: byte = 30;
MemoPageSize = 512;
DbTempFname:string[12] = 'delete.me';
type
ShowNdxProgressProc = procedure( KeysWritten, TotRecords: longint; Status: byte );
HeaderPtr = ^HeaderInfo;
HeaderInfo = record
VersionNumber: byte;
Update: array [1..3] of byte;
NbrRec: longint;
HdrLen: integer;
RecLen: integer;
Reserved: array [1..20] of char;
end;
FieldPtr = ^FieldDesc;
FieldDesc = record
FdName: array [1..11] of char;
FdType: char;
Reserved1: array [1..4] of char;
FdLength: byte;
FdDec: byte;
Reserved2: array [1..14] of char;
end;
MemoPtr = ^MemoDesc;
MemoDesc = record
NextMemoRec: longint;
LastMemoRec: longint;
EmptySpace: array [1..508] of char;
end;
GdbBaseWrkSpc = array [1..MaxRecLen] of char;
GdbNdxWrkSpc = array [1..MaxNdxLen] of char;
WrkSpcPtr = ^GdbBaseWrkSpc;
NdxSpcPtr = ^GdbNdxWrkSpc;
DBStatus = record { information pertaining to DataSet }
DbtAlias: file;
NdxAlias: file;
DbfAlias: file;
DBPath: PathStr;
DbtName: PathStr;
NdxName: PathStr;
DbfName: PathStr;
SaveIndexFldValue: boolean;
DeletingIndexEntry: boolean;
DFOpen: boolean;
MFOpen: boolean;
vHdrModified: boolean;
MemoIsIncluded: boolean;
RecStatus: byte;
IndexField: integer;
NdxFldLen: integer;
IndexUpperCase: boolean;
pHead: HeaderPtr;
pField: FieldPtr;
pMemo: MemoPtr;
FldInfo: SingleLL;
WrkSpc: WrkSpcPtr;
NdxSpc: NdxSpcPtr;
BakNdxSpc: NdxSpcPtr;
Fpos: longint;
CurrentRec: longInt;
end;
DBListNodePtr = ^DBListNode;
DBListNode = record
DBInfo: DBStatus;
NextPtr: DBListNodePtr;
end;
DBSet = record { global information }
DbfCFld,
DbfNFld,
DbfLFld,
DbfDFld,
DbfMFld: char;
HasMemo,
ClosingAll,
FldLstIsActive,
FullStrings,
Packing: boolean;
MemoSize,
LastECode: integer;
EMsgFunc: ErrMsgFunc;
ShowNdxProgress: ShowNdxProgressProc;
DbfFieldList: SingleLL;
StartNode: DBListNodePtr;
ActiveNode: DBListNodePtr;
DBsOpen: integer;
Actual: word;
end;
{dbf procs}
function DbOpenDataSet(DBFile: pathstr): integer;
procedure DbSetActiveDataBase(Handle:integer);
function LastDBError: integer;
function DBFExist(FN: PathStr): boolean;
function DbGetVersion: byte;
function DbGetUpDate: dates;
procedure DbPutUpDate;
function DbTotalFields: integer;
function DbGetNumRecs: longint;
function DbCurrRecNum: longint;
function DbGetHdrLen: integer;
function DbGetRecLen: word;
function DbRecordIsActive(RecNo: longint): boolean;
procedure DbSetFullStrings(On: boolean);
function DbGetFldName(FieldNo: integer): string;
function DbGetFldType(FieldNo: integer): char;
function DbGetFldLength(FieldNo: integer): integer;
function DbGetFldDec(FieldNo: integer): integer;
function DbIndexedField: integer;
function DbGetFldString(RecNo: longint; FieldNo: integer): string;
function DbGetFldInt(RecNo: longint; FieldNo: integer): integer;
function DbGetFldLong(RecNo: longint; FieldNo: integer): longint;
function DbGetFldReal(RecNo: longint; FieldNo: integer): extended;
function DbGetFldLogical(RecNo: longint; FieldNo: integer): boolean;
procedure DbGetFldMemo(RecNo: longint; FieldNo: integer;var MemoDetails:MemoCfg);
function DbGetMemoRecNum(RecNo:longint;FieldNo:integer):longint;
function DbSetFldMemo(FldNo: integer;var SL: SingleLL): longint;
function DbGetFldDate(RecNo: longint; FieldNo: integer): Dates;
procedure DbSetFldString(FieldNo: integer; StrVar: string);
procedure DbSetFldInt(FieldNo: integer; IntVar: longint);
procedure DbSetFldReal(FieldNo: integer; RealVar: Extended);
procedure DbSetFldLogical(FieldNo: integer; BoolVar: boolean);
procedure DbSetFldDate(FieldNo: integer; DateVar: longint);
function DbFldIsEmpty(RecNo: longint;FieldNo: integer):boolean;
procedure DbClearWrkSpc;
procedure DbPutHeader(var Alias: file);
procedure DbAddRecord;
procedure DbDeleteRecord(RecNo: longint);
procedure DbUnDeleteRecord(RecNo: longint);
procedure DbGetRecord(RecNo: longint);
procedure DbPutRecord;
function DbSeqSearch(var RecNo: longint; FieldNo: integer; SearchTxt: String): boolean;
function DbPackFile(FName: PathStr; IndexField: integer): integer;
procedure DbCloseDataBase(Handle: integer);
procedure DbCloseAllDatabases;
{dbf creation procs}
function DbAddDbfField(FldName: string; FldType: char; FldLen, FldDecPl: integer): integer;
function DbBuildDataFile( FN: Pathstr; NDXFld : byte): integer;
procedure DbBuildMemoFile(FName:PathStr);
function DbRebuildMemo(FName: PathStr): integer;
function DbFindFirst(FieldNo: integer; var findValue; PartialMatch: boolean): longint;
function DbFindNext: longInt;
{ndx procs}
procedure SetShowNdxProgress(Proc: ShowNdxProgressProc);
function NdxGotoFirst: longint;
function NdxGotoLast: longint;
function NdxGotoNext: longint;
function NdxGotoPrev: longint;
function NdxValidate(Partial: boolean): byte;
function NdxRebuild: integer;
function NdxBuildNew(FieldNo: integer): integer;
function NdxGetRecNum(EntryNum: longInt) : longInt;
procedure NdxSetMaxPages(n: Word);
procedure NdxSetUpperCase(x: boolean);
procedure NdxSetMaxStrLength(n: Byte);
function NdxCount : longint;
var
DbVars: DBSet;
{+++++++++++++++++++++++++++++} IMPLEMENTATION {+++++++++++++++++++++++++++++}
{**********************************}
{** Miscellaneous Routines **}
{**********************************}
{$IFOPT F-}
{$DEFINE FOFF}
{$F+}
{$ENDIF}
function DbEMsg(ECode:integer): string;
{}
begin
case Ecode of
2 : DbEMsg := 'File was not found in current directory';
4 : DbEMsg := 'Too many open files';
8 : DbEMsg := 'Insufficient memory for allocation';
100 : DbEMsg := 'Unable to read from media';
101 : DbEMsg := 'Unable to write to file';
102 : DbEMsg := 'Assign must be called first';
103 : DbEMsg := 'File has not been successfully opened';
104 : DbEMsg := 'File must be opened for input first';
105 : DbEMsg := 'File must be opened for output first';
106 : DbEMsg := 'An invalid numeric format has been encountered';
150 : DbEMsg := 'Disk is write protected';
151 : DbEMsg := 'Unknown unit';
152 : DbEMsg := 'Drive not ready';
153 : DbEMsg := 'Unknown command';
154 : DbEMsg := 'CRC error in data';
155 : DbEMsg := 'Bad drive request structure length';
156 : DbEMsg := 'Disk seek error';
157 : DbEMsg := 'Unknown media type';
158 : DbEMsg := 'Sector not found';
159 : DbEMsg := 'Printer out of paper';
160 : DbEMsg := 'Device write fault';
161 : DbEMsg := 'Device read fault';
162 : DbEMsg := 'Hardware failure';
900..999 : { close file errors }
DbEMsg := 'Close failure';
1000: DbEMsg := 'Number of fields cannot exceed 127';
1001: DbEMsg := 'Nothing to do';
1002: DbEMsg := 'Value must be >= current value contained in pHead^.NbrRec';
1003: DbEMsg := 'Invalid value, Header Length';
1004: DbEMsg := 'Record Length must be greater than zero';
1005: DbEMsg := 'Invalid Field Name, could not be set';
1006: DbEMsg := 'Field type invalid, Field type not set';
1007: DbEMsg := 'Field length is out of range, unable to set';
1008: DbEMsg := 'No records available';
1009: DbEMsg := 'Insufficient heap available to move header';
1010: DbEMsg := 'Not a valid dbf file or file is corrupted';
1012: DbEMsg := 'Field type must be ''N'' for decimals to be greater than zero';
1013: DbEMsg := 'Unable to get record';
1014: DbEMsg := 'Unable to delete record';
1015: DbEMsg := 'Unable to undelete record';
1016: DbEMsg := 'Unable to determine record status';
1017: DbEMsg := 'Error in key string';
1018: DbEMsg := 'Memo file already exists';
1019: DbEMsg := 'Cannot activate database; closed or inactive handle';
1020: DbEMsg := 'Insufficient heap available to init Database';
1021: DbEMsg := 'Unable to locate DBF (data) file';
1022: DbEMsg := 'Unable to locate NDX (index) file';
1023: DbEMsg := 'Unable to locate DBT (memo) file';
1024: DbEMsg := 'Not enough memory to create DBF Header';
1025: DbEMsg := 'Error building field list from header';
1026: DbEMsg := 'Field is not a String field';
1027: DbEMsg := 'Field is not a Numeric field';
1028: DbEMsg := 'Field is not a Boolean field';
1029: DbEMsg := 'Field is not a Memo field';
1030: DbEMsg := 'InValid function call, Memo field not included';
1031: DbEMsg := 'Field is not a Date field';
1032: DbEMsg := 'Record number is out-of-range';
1033: DbEMsg := 'Error building new memo file';
1034: DbEMsg := 'Unable to open memo file';
1035: DbEMsg := 'DBT corrupt';
1036: DbEMsg := 'Error resetting DBT file to access memo';
1037: DbEMsg := 'Error writing memo to DBT file';
1038: DbEMsg := 'Unable to create DBT';
1039: DbEMsg := 'Unable to create DBF file';
1052: DbEMsg := 'Field Number is out-of-range';
1067: DbEMsg := 'Memo''s can only be read into SLL assigned MemoCFG''s';
1085: DbEMsg := 'Index rebuild failure during pack, potential corruption';
1086: DbEMsg := 'Unable to create datafile; no fields defined';
1087: DbEMsg := 'Unable to delete index file';
1088: DbEMsg := 'Error rebuilding memo file';
1101..1150 : { read errors }
DbEMsg := 'Read Error, '+IntToStr(ECode);
1151..1200 : { write errors }
DbEMsg := 'Write Error, '+IntToStr(ECode);
1201..1250 : { seek errors }
DbEMsg := 'Seek Error, '+IntToStr(ECode);
1251..1300 : { reset errors }
DbEMsg := 'Reset Error, '+IntToStr(ECode);
1301..1350 : { rewrite errors }
DbEMsg := 'Rewrite Error, '+IntToStr(ECode);
2000: DbEMsg := 'Unable to open index file';
2001: DbEMsg := 'Not a valid index file';
else
DbEMsg := 'Internal database error';
end; {case}
end; { DbEMsg }
procedure NoProgressHook( KeysWritten,Records: longint; Status:byte);
{ empty proc }
begin
{abstract}
end; { NoProgressHook }
{$IFDEF FOFF}
{$F-}
{$UNDEF FOFF}
{$ENDIF}
procedure DBSetError(ECode:integer);
{}
{$IFOPT D+}
var Msg: StrScreen;
{$ENDIF}
begin
DbVars.LastEcode := ECode;
{$IFOPT D+} {if debug active display an error message and terminate}
if Ecode <> 0 then
begin
str(Ecode,Msg);
Msg := Msg+': '+DBVars.EMsgFunc(Ecode);
SetWinIgnore(true);
if PromptCustom(' GoldDB Error ',Msg,' ~I~gnore ',' ~A~bort ','',279,286,0,0, 10000) = 2 then
Halt;
end;
{$ENDIF}
end; { DBSetError }
procedure AllocateNdxSpc;
{}
begin
with DbVars.ActiveNode^.DBInfo do
begin
if IndexField > 0 then
begin
getmem(NdxSpc,NdxFldLen);
getmem(BakNdxSpc,NdxFldLen);
end;
end;
end; { AllocateNdxSpc }
{$I GoldNDX.INC}
function SizeOfData: longint;
{}
begin
SizeOfData := ( sizeof(DBListNode) + { 766 }
sizeof(HeaderInfo) + { 32 }
sizeof(FieldDesc) + { 32 }
sizeof(MemoDesc) + { 516 }
sizeof(GdbBaseWrkSpc) + { 4000 }
(sizeof(GdbNdxWrkSpc)*2)); { 490 } {=} { 5836 }
end;
function DbInitDatabase: integer;
{Returns the DB ID of the newly opened database or 0 if failed}
var
Temp: DBListNodePtr;
ID:word;
begin
DbInitDataBase := 0;
if GoldMaxAvail < SizeOfData then
DBSetError(1020) { Insufficient heap available to init Database }
else
begin
if DbVars.StartNode = nil then
begin
getmem(DbVars.StartNode,sizeof(DbVars.StartNode^));
Temp := DbVars.StartNode;
ID := 1;
end else
begin
Temp := DbVars.StartNode;
ID := 1;
while Temp^.NextPtr <> nil do
begin
Temp := Temp^.NextPtr;
inc(ID);
end;
getmem(Temp^.NextPtr, sizeof(Temp^.NextPtr^));
inc(ID);
Temp := Temp^.NextPtr;
end;
Temp^.NextPtr := nil;
with Temp^.DBInfo do
begin { initialize DB stuff }
fillchar(Temp^.DBInfo,sizeof(Temp^.DBInfo),#0);
SaveIndexFldValue := true;
getmem(pHead,sizeof(pHead^));
getmem(pField,sizeof(pField^));
end;
DbVars.ActiveNode := Temp;
DbInitDataBase := ID;
inc(DbVars.DBsOpen);
end;
end; { DbInitDataBase }
procedure DbSetActiveDataBase(Handle:integer);
{}
var
Temp: DBListNodePtr;
I: integer;
begin
if ( Handle > 0 ) then
with DbVars do
begin
Temp := ActiveNode;
ActiveNode := StartNode;
for I := 2 to Handle do
begin
if DbVars.ActiveNode <> nil then
ActiveNode := ActiveNode^.NextPtr;
end;
if (ActiveNode = nil) or ( not ActiveNode^.DBInfo.DFOpen ) then
begin
ActiveNode := Temp; { No change }
DBSetError(1019); { Cannot activate database; closed or inactive handle }
end;
end;
end; { DbSetActiveDataBase }
function LastDBError: integer;
{}
begin
LastDBError := DbVars.LastEcode;
DbSetError(0); { clear LastEcode }
end; { LastDBError }
function DBFExist(FN: PathStr): boolean;
{}
var Drv: string[1];
FullStr, Pth: PathStr;
Name: string[8];
SR: SearchRec;
begin
Drv := FileDrive(FN);
Pth := FileDirectory(FN);
Name := FileName(FN);
if Drv <> '' then
Drv := Drv + ':';
if Pth <> '' then
FullStr := Drv + SlashedDirectory(Pth) + Name + DFX
else
FullStr := Drv + Name + DFX;
FindFirst(FullStr,Anyfile-Hidden-Directory-SysFile-VolumeID,SR);
DBFExist := DosError = 0;
end; { DBFExist }
function DbGetVersion: byte;
{}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo.pHead^ do
DbGetVersion := VersionNumber;
end; { DbGetVersion }
function DbGetUpDate: dates;
{ Date is in the form of YY MM DD }
var
TmpByte: array[1..3] of byte;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo.pHead^ do
begin
move(UpDate,TmpByte,sizeof(TmpByte));
DBgetUpdate := GregToJul(TmpByte[2],TmpByte[3],1900+TmpByte[1]);
end;
end; { DbGetUpDate }
procedure DbPutUpDate;
{Date of most recent change to file}
var vYear,vMth,vDay,vDow: word;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
getdate(vYear,vMth,vDay,vDow); { Current System Date }
pHead^.Update[1] := vYear-1900;
pHead^.Update[2] := vMth;
pHead^.Update[3] := vDay;
vHdrModified := true;
end;
end; { DbPutUpDate }
function DbTotalFields: integer;
{}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^ do
DbTotalFields := ( DbGetHdrLen - 33 ) div 32;
end; { DbTotalFields }
function DbGetNumRecs: longint;
{}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo.pHead^ do
DbGetNumRecs := NbrRec;
end; { DbGetNumRecs }
function DbCurrRecNum: longint;
{}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
DbCurrRecNum := CurrentRec;
end; { DbCurrRecNum }
function DbGetMemoRecNum(RecNo:longint;FieldNo:integer):longint;
{}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
DbGetMemoRecNum := DbGetFldLong(RecNo,FieldNo);
end; { DbGetMemoRecNum }
procedure DbPutNumRecs(Amount: longint);
{internal}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
if ( Amount > DbGetNumRecs ) or DbVars.Packing then
begin
pHead^.NbrRec := Amount;
vHdrModified := true;
end else
DBSetError(1002);
end;
end; { DbPutNumRecs }
function DbGetHdrLen: integer;
{}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
DbGetHdrLen := pHead^.HdrLen;
end; { DbGetHdrLen }
function DbGetRecLen: word;
{}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
DbGetRecLen := pHead^.RecLen;
end; { DbGetRecLen }
function RecIsWithinRange(RecNo: longint): boolean;
{}
begin
RecIsWithinRange := ((RecNo >= 1) and (RecNo <= DbGetNumRecs));
end; { RecIsWithinRange }
function FldIsWithinRange(FieldNo: integer): boolean;
{}
begin
FldIsWithinRange := ((FieldNo >= 1) and (FieldNo <= DbTotalFields));
end; { FldIsWithinRange }
function DbRecordIsActive( RecNo: longint ): Boolean;
{}
var TmpB: boolean;
begin
DbRecordIsActive := false;
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
if RecIsWithinRange(RecNo) then
begin
if RecNo <> CurrentRec then
DbGetRecord(RecNo);
case WrkSpc^[1] of
' ' : TmpB := true;
'*' : TmpB := false;
else
DBSetError(1016); { Unable to determine record status }
end;
end;
end;
DbRecordIsActive := TmpB;
end; { DbRecordIsActive }
procedure DbSetFullStrings(On: boolean);
{}
begin
DbVars.FullStrings := On;
end; { DbSetFullStrings }
function DbGetFldName( FieldNo: integer ): string;
{}
var TempStr: string;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^ do
begin
TempStr := _SLLGetNodeStr(DbInfo.FldInfo,_SLLNodePtr(DbInfo.FldInfo,FieldNo),255);
DbGetFldName := copy(TempStr,1,pred(pos(#0,TempStr)));
end;
end; { DbGetFldName }
function DbGetFldType( FieldNo: integer ): char;
{}
var Ch: string[1];
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^ do
Ch := copy(_SLLGetNodeStr(DbInfo.FldInfo,_SLLNodePtr(DBInfo.FldInfo,FieldNo),255),12,1);
DbGetFldType := ch[1];
end; { DbGetFldType }
function DbGetFldLength( FieldNo: integer ): integer;
{}
var TempStr: string;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^ do
begin
{$IFDEF CHECK}
if (FieldNo < 1) or (FieldNo > DbTotalFields) then
begin
DbSetError(1052); { FieldNo is out-of-range }
DbGetFldLength := 0;
end;
{$ENDIF}
TempStr := _SLLGetNodeStr(DBInfo.FldInfo,_SLLNodePtr(DBInfo.FldInfo,FieldNo),255);
DbGetFldLength := integer(TempStr[17]); { length byte }
end;
end; { DbGetFldLength }
function DbGetFldDec( FieldNo: Integer ): integer;
{}
var TempStr: string;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^ do
begin
TempStr := _SLLGetNodeStr(DBInfo.FldInfo,_SLLNodePtr(DBInfo.FldInfo,FieldNo),255);
DbGetFldDec := integer(TempStr[18]); { decimal byte }
end;
end; { DbGetFldDec }
function StrtPos(FieldNo: integer): integer;
{}
var TmpPos, I: integer;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
TmpPos := 2; { must account for status byte + 1 }
if FieldNo <> 1 then
for I := pred(FieldNo) downto 1 do
inc(TmpPos,DbGetFldLength(I));
StrtPos := TmpPos;
end;
end; { StrtPos }
procedure BakUpNdxSpc;
{}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
if (NdxSpc <> nil) and (BakNdxSpc <> nil) then
move(NdxSpc^,BakNdxSpc^,NdxFldLen);
end; { BakUpNdxSpc }
function GetField(RecNo: longint; FieldNo: integer): string;
{internal}
var Len: integer;
TempStr: string;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
GetField := '';
if (FieldNo = IndexField) and (DeletingIndexEntry) then
begin
move(BakNdxSpc^,TempStr[1],NdxFldLen);
TempStr[0] := chr(NdxFldLen);
GetField := TempStr;
end
else if RecIsWithinRange(RecNo) then
begin
if FldIsWithinRange(FieldNo) then
begin
if (RecNo <> CurrentRec) then
DbGetRecord(RecNo);
Len := DbGetFldLength(FieldNo);
move(WrkSpc^[StrtPos(FieldNo)],TempStr[1],Len);
TempStr[0] := chr(Len);
GetField := TempStr;
if NdxSpc = nil then
AllocateNdxSpc;
if FieldNo = IndexField then
move(TempStr[1],NdxSpc^,NdxFldLen);
end
else
DBSetError(1052); { Field number out-of-range }
end
else
DBSetError(1032); { Record Number out-of-range }
end;
end; { GetField }
function DbIndexFieldChanged: boolean;
{}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
DbIndexFieldChanged := Different(NdxSpc^,WrkSpc^[StrtPos(IndexField)],NdxFldLen);
end; { DbIndexFieldChanged }
function DbIndexedField: integer;
{}
begin
with DbVars.ActiveNode^.DBInfo do
DbIndexedField := IndexField;
end; { DbIndexedField }
function DbGetFldString(RecNo: longint; FieldNo: integer): string;
{}
var TmpStr: string;
Len: integer;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
TmpStr := GetField(RecNo,FieldNo);
if DbVars.FullStrings then
DbGetFldString := TmpStr
else
DbGetFldString := Strip('R',' ',TmpStr);
end;
end; { DbGetFldString }
function DbGetFldInt(RecNo: longint; FieldNo: integer): integer;
{}
var TmpStr: string;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
DbGetFldInt := 0;
if DbGetFldType(FieldNo) = DbVars.DbfNFld then
begin
TmpStr := GetField(RecNo,FieldNo);
DbGetFldInt := StrToInt(TmpStr);
end else
DbSetError(1027); { not a numeric field }
end;
end; { DbGetFldInt }
function DbGetFldLong(RecNo: longint; FieldNo: integer): longint;
{}
var TmpStr: string;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
DbGetFldLong := 0;
if (DbGetFldType(FieldNo) IN [DBVars.DbfNFld,DBVars.DbfMFld]) then
begin
TmpStr := GetField(RecNo,FieldNo);
DbGetFldLong := StrToLong(TmpStr);
end else
DbSetError(1027); { not a numeric field }
end;
end; { DbGetFldLong }
function DbGetFldReal(RecNo: longint; FieldNo: integer): extended;
{}
var TmpStr: string;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
DbGetFldReal := 0.0;
if DbGetFldType(FieldNo) = DbVars.DbfNFld then
begin
TmpStr := GetField(RecNo,FieldNo);
DbGetFldReal := StrToReal(TmpStr);
end else
DbSetError(1027); { not a numeric field }
end;
end; { DbGetFldReal }
function DbGetFldLogical(RecNo: longint; FieldNo: integer): boolean;
{}
var TmpStr: string;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
DbGetFldLogical := false;
if DbGetFldType(FieldNo) = DbVars.DbfLFld then
begin
TmpStr := GetField(RecNo,FieldNo);
DbGetFldLogical := (TmpStr = 'T');
end else
DbSetError(1028); { not a logical field }
end;
end; { DbGetFldLogical }
procedure DbGetFldMemo(RecNo: longint; FieldNo: integer;var MemoDetails:MemoCfg);
{}
const
SLLNodeLen = 128;
var
MemoVar: longint;
MemoBuf: array [0..pred(MemoPageSize)] of char;
I: byte;
TempStr: string;
TempNP: SingleNodePtr;
procedure PassToSL;
{}
var
WorkStr: string[SLLNodeLen];
Counter: integer;
P,StrLen: byte;
begin
Counter := 0;
while Counter < I do {I is number of lines to read}
begin
StrLen := GetMin(SLLNodeLen,I - Counter);
move(MemoBuf[Counter],WorkStr[1],StrLen);
WorkStr[0] := chr(StrLen);
{replace CRLF's with end of para codes}
repeat
P := pos(CRLF,WorkStr);
if P > 0 then
begin
delete(Workstr,P,length(CRLF));
insert(MemoVars.EndofParaCode,WorkStr,P);
end;
until P = 0;
if _SLLAddStr(SingleLL(MemoDetails.DataSource^),WorkStr) <> 0 then
DbSetError(1105); { Error reading memo file }
inc(Counter,StrLen);
end;
end; { PassToSL }
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
if MFOpen then
begin
if DbGetFldType(FieldNo) <> DbVars.DbfMFld then
DbSetError(1029) { not a memo field }
else
begin
{$I-} reset(DbtAlias,1); {$I+}
if IOResult <> 0 then
begin
DbSetError(1036); { error reseting dbt file to access memo }
exit;
end
else
begin
MemoVar := DbGetFldLong(RecNo,FieldNo);
if MemoDetails.DataType <> SourceSLL then
begin
DbSetError(1067);
exit
end;
_SLLDestroy(SingleLL(MemoDetails.DataSource^)); {remove any old entries}
if (MemoVar <= pMemo^.LastMemoRec) and (MemoVar > 0) then
begin
{$I-} seek(DbtAlias,(MemoVar*MemoPageSize)); {$I+}
if IOResult <> 0 then
begin
DbSetError(1204); { Seek error Reading memo file }
exit;
end;
DbVars.MemoSize := 0;
repeat
I := 0;
blockread(DbtAlias,MemoBuf,MemoPageSize,DbVars.Actual);
while (MemoBuf[I] <> char(EOM)) and (I < DbVars.Actual) do
begin
inc(DbVars.MemoSize);
inc(I);
end;
PassToSL;
until (MemoBuf[I] = char(EOM)) or (MemoPageSize <> DbVars.Actual);
Memodetails.TotalNodes := SingleLL(MemoDetails.DataSource^).TotalNodes;
{check for end of para; if not there, add one}
TempStr := _SLLGetStr(SingleLL(MemoDetails.DataSource^),SingleLL(MemoDetails.DataSource^).TotalNodes);
if TempStr[length(TempStr)] <> MemoVars.EndofParaCode then
begin
TempStr := TempStr + MemoVars.EndofParaCode;
TempNP := _SLLNodePtr(SingleLL(MemoDetails.DataSource^),SingleLL(MemoDetails.DataSource^).TotalNodes);
if _SLLChangeStr(SingleLL(MemoDetails.DataSource^),TempNP,TempStr) <> 0 then {whocares};
end;
{if wordwrap is on, wrap the field}
{$IFDEF WORDWRAP}
if MemoDetails.WordWrap then
WrapFull(MemoDetails);
{$ENDIF}
end;
end;
end;
end;
end;
end; { DbGetFldMemo }
function DbGetFldDate(RecNo: longint; FieldNo: integer): Dates;
{}
var TmpStr: string;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
DbGetFldDate := 0;
if DbGetFldType(FieldNo) = DbVars.DbfDFld then
begin
TmpStr := GetField(RecNo,FieldNo);
DbGetFldDate := StrToJul(TmpStr,YYYYMMDD);
end else
DbSetError(1031); { not a date field }
end;
end; { DbGetFldDate }
procedure DbSetFldString(FieldNo: integer; StrVar: string);
{}
var SPos, Len: integer;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
if DbGetFldType(FieldNo) <> DbVars.DbfCFld then
DbSetError(1026) { field is not a string field }
else
begin
if FieldNo = IndexField then
begin
BakUpNdxSpc; { copies NdxSpc to BakNdxSpc }
Len := NdxFldLen;
end else
Len := DbGetFldLength(FieldNo);
StrVar := PadLeft(StrVar,Len,#32);
SPos := StrtPos(FieldNo);
move(StrVar[1],WrkSpc^[SPos],Len);
end
end;
end; { DbSetFldString }
procedure DbSetFldInt(FieldNo: integer; IntVar: longint);
{}
var SPos, Len: integer;
StrIntVar: string;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
if DbGetFldType(FieldNo) <> DbVars.DbfNFld then
DbSetError(1027) { field is not numeric }
else
begin
if FieldNo = IndexField then
begin
BakUpNdxSpc;
Len := NdxFldLen;
end else
Len := DbGetFldLength(FieldNo);
StrIntVar := PadRight(IntToStr(IntVar),Len,#32);
SPos := StrtPos(FieldNo);
move(StrIntVar[1],WrkSpc^[SPos],Len);
end;
end;
end; { DbSetFldInt }
procedure DbSetFldReal(FieldNo: integer; RealVar: Extended);
{}
var SPos, Len: integer;
StrRealVar: string;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
if DbGetFldType(FieldNo) <> DbVars.DbfNFld then
DbSetError(1027) { field is not numeric }
else
begin
if FieldNo = IndexField then
begin
BakUpNdxSpc;
Len := NdxFldLen;
end else
Len := DbGetFldLength(FieldNo);
StrRealVar := PadRight(RealToStr(RealVar,DbGetFldDec(FieldNo)),Len,#32);
SPos := StrtPos(FieldNo);
move(StrRealVar[1],WrkSpc^[SPos],Len);
end;
end;
end; { DbSetFldReal }
procedure DbSetFldLogical(FieldNo: integer; BoolVar: boolean);
{}
var SPos: integer;
StrBoolVar: char;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
if DbGetFldType(FieldNo) <> DbVars.DbfLFld then
DbSetError(1028) { field is not boolean }
else
begin
if Boolvar then
StrBoolVar := 'T'
else
StrBoolVar := 'F';
if FieldNo = IndexField then
BakUpNdxSpc;
SPos := StrtPos(FieldNo);
Move(StrBoolVar,WrkSpc^[SPos],1);
end;
end;
end; { DbSetFldLogical }
procedure DbSetMemoRecNum(FieldNo:integer;MemoRecNo:longint);
{}
var SPos: integer;
StrMemoVar: string[10];
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
if DbGetFldType(FieldNo) <> DbVars.DbfMFld then
DbSetError(1029) { field is not memo }
else begin
StrMemoVar := PadRight(IntToStr(MemoRecNo),10,' ');
SPos := StrtPos(FieldNo);
Move(StrMemoVar[1],WrkSpc^[SPos],10);
end;
end;
end; { DbSetMemoRecNum }
function DbSetFldMemoEngine(FldNo: integer; var SL: SingleLL;
var FAlias: file; var NextMemoRec,LastMemoRec:longint): longint;
{Stores memo data in .dbt file and updates memo variable}
const
PadChar: char = 'G';
var
RecNum: longint;
Ch: char;
I, Counter: integer;
MemoBuf: array [0..pred(MemoPageSize)] of char;
Str: string;
SNP: SingleNodePtr;
procedure StrtoBuf;
{}
var P,S: byte;
begin
{first, replace endofpara codes with CRLF}
repeat
P := pos(MemoVars.EndofParaCode,Str);
if P <> 0 then
begin
delete(Str,P,length(MemoVars.EndofParaCode));
insert(CRLF,Str,P);
end;
until P = 0;
S := GetMin(length(Str),(MemoPageSize - Counter));
move(Str[1],MemoBuf[Counter],S);
inc(Counter,S);
delete(Str,1,S);
end; { StrtoBuf }
begin
DbSetFldMemoEngine := 1; { failure }
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
RecNum := NextMemoRec; {used to update the DBF fld at end of proc}
if NextMemoRec > 1 then
begin
{$I-} seek(FAlias,LastMemoRec * MemoPageSize); {$I+}
if IOResult <> 0 then
begin
DbSetError(1205); { Error seeking while storing memo }
exit;
end;
{scour along last memo in file looking for EOM}
Counter := 0;
repeat
inc(Counter);
blockread(FAlias,Ch,1,DbVars.Actual);
if DbVars.Actual <> 1 then
begin
DbSetError(1106); { Error reading memo file while seeking EOM }
exit;
end;
until Ch=char(EOM);
for I := 1 to (MemoPageSize - Counter) do {pad the page to MemoPageSize}
begin
blockwrite(FAlias,PadChar,1,DbVars.Actual);
if DbVars.Actual <> 1 then
begin
DbSetError(1037);
exit;
end;
end;
end
else
begin
{$I-} seek(FAlias, MemoPageSize); {$I+}
if IOResult <> 0 then
begin
DbSetError(1205); { Error seeking while storing memo }
exit;
end;
end;
{now we are positioned at the end of the file with all
previous memos (if any) occupying MemoPageSize bytes}
Str := '';
Counter := 0;
SNP := _SLLNodePtr(SL,1);
while (Str <> '') or (SNP <> nil) do
begin
if Str = '' then
begin
Str := _SLLGetNodeStr(SL,SNP,0);
SNP := SNP^.NextPtr;
end;
StrToBuf;
if Counter = MemoPageSize then
begin
blockwrite(FAlias,MemoBuf,MemoPageSize,DbVars.Actual);
if DbVars.Actual <> MemoPageSize then
begin
DbSetError(1037);
exit;
end;
inc(NextMemoRec);
Counter := 0;
end;
end;
if Counter <> 0 then {need to flush the buffer to disk}
begin
blockwrite(FAlias,MemoBuf,Counter,DbVars.Actual);
if DbVars.Actual <> Counter then
begin
DbSetError(1037);
exit;
end;
inc(NextMemoRec);
end;
if Counter = 511 then {the two extra bytes will spill into the next page}
inc(NextMemoRec);
{time to write the end-of-memo characters twice}
for I := 1 to 2 do
begin
blockwrite(FAlias,EOM,1,DbVars.Actual);
if DbVars.Actual <> 1 then
begin
DbSetError(1037);
exit;
end;
end;
{$I-} seek(FAlias,0); {$I+}
if IOResult <> 0 then
begin
DbSetError(110);
exit;
end;
blockwrite(FAlias,NextMemoRec,sizeof(NextMemoRec),DbVars.Actual);
if DbVars.Actual <> sizeof(NextMemoRec) then
DbSetError(1037)
else
begin
DbSetMemoRecNum(FldNo,RecNum);
DbSetFldMemoEngine := 0;
end;
LastMemoRec := pred(NextMemoRec);
end; { DbSetFldMemoEngine }
function DbSetFldMemo(FldNo: integer; var SL: SingleLL): longint;
begin
with DbVars.ActiveNode^,DBInfo,pMemo^ do
begin
if MFOpen then
DbSetFldMemo := DbSetFldMemoEngine(FldNo,SL,DBTAlias,NextMemoRec,LastMemoRec)
else
DbSetFldMemo := 1;
end
end; { DbSetFldMemo }
procedure DbSetFldDate(FieldNo: integer; DateVar: longint);
{}
var SPos: integer;
StrDateVar: string;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
if DbGetFldType(FieldNo) <> DbVars.DbfDFld then
DbSetError(1031) { field is not a date field }
else
begin
if FieldNo = IndexField then
BakUpNdxSpc;
StrDateVar := StripDateStr(JulToStr(DateVar,YYYYMMDD),YYYYMMDD);
SPos := StrtPos(FieldNo);
Move(StrDateVar[1],WrkSpc^[SPos],8);
end;
end;
end; { DbSetFldDate }
function DbFldIsEmpty(RecNo: longint;FieldNo: integer): boolean;
{}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
DbFldIsEmpty := (Strip('A',' ',GetField(RecNo,FieldNo)) = '');
end; { DbFldIsEmpty }
procedure DbClearWrkSpc;
{}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
fillchar(WrkSpc^,DbGetRecLen,#32);
end; { DbClearWrkSpc }
procedure DbPutHeader( var Alias: file );
{}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
DbPutUpDate; { update current date }
{$I-} seek(Alias,0); {$I+}
if IOResult <> 0 then
DbSetError(1206) { Seek error while updating header }
else
begin
blockwrite(Alias,pHead^,sizeof(pHead^),DbVars.Actual);
if DbVars.Actual <> sizeof(pHead^) then
DbSetError(1161); { Write error while updating header info }
vHdrModified := false;
end;
end;
end; { DBPutHeader }
procedure DbAddRecord;
{}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
WrkSpc^[1] := #32; { set to active }
FPos := DbGetHdrLen + ( DbGetNumRecs * DbGetRecLen );
{$I-} seek(DBFAlias,FPos); {$I+} { Set file pointer to end of file }
if IOResult <> 0 then
DbSetError(1207) { Unable to seek to EOF to add record }
else
begin
blockwrite(DBFAlias,WrkSpc^[1],DbGetRecLen,DbVars.Actual);
if DbVars.Actual <> DbGetRecLen then
DbSetError(1162) { Unable to write new record, blockwrite failed }
else
begin
blockwrite(DBFAlias,EOFile,sizeof(EOFile),DbVars.Actual); { Write EOF }
if DbVars.Actual <> sizeof(EOFile) then
DbSetError(1163) { Unable to write EOF while adding new record }
else
begin
DbPutNumRecs(succ(DbGetNumRecs));
DbPutHeader(DBFAlias);
CurrentRec := DbGetNumRecs;
if IndexField <> 0 then
begin
NdxAddKey;
move(WrkSpc^[StrtPos(IndexField)],NdxSpc^,NdxFldLen);
end;
end;
end;
end;
end;
end; { DbAddRecord }
procedure DbDeleteRecord( RecNo: longint );
{}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
if RecNo <> DbCurrRecNum then
DbGetRecord(RecNo);
if (WrkSpc^[1] = chr(Space)) then
begin
WrkSpc^[1] := chr(Astk);
DbPutRecord;
if IndexField <> 0 then
NdxDelKey(RecNo);
end;
end;
end; { DbDeleteRecord }
procedure DbUnDeleteRecord( RecNo: longint );
{}
var OK: boolean;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
if RecNo <> DbCurrRecNum then
DbGetRecord(RecNo);
if (WrkSpc^[1] = chr(Astk)) then
begin
WrkSpc^[1] := chr(Space);
DbPutRecord;
if IndexField <> 0 then
NdxAddKey;
end;
end;
end; { UnDeleteRecord }
procedure DbGetRecord( RecNo: longint );
{}
var TmpNdx: string[MaxNdxLen];
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
if ( RecNo < 1 ) OR ( RecNo > 1048576 ) then
DBSetError(1032) { Out-of-range }
else
begin
FPos := DbGetHdrLen + ( pred(RecNo) * DbGetRecLen );
{$I-} seek(DBFAlias,FPos); {$I+}
if IOResult <> 0 then
DbSetError(1213) { Seek error within DbGetRecord }
else
begin
blockread(DBFAlias, WrkSpc^[1], DbGetRecLen, DbVars.Actual);
if DbVars.Actual <> DbGetRecLen then
DbSetError(1067) { Read error within DbGetRecord }
else
begin
CurrentRec := RecNo;
if SaveIndexFldValue and (IndexField <> 0) then
begin
if NdxSpc = nil then
AllocateNdxSpc;
move(WrkSpc^[StrtPos(IndexField)],NdxSpc^,NdxFldLen);
end;
end;
end;
end;
end;
end; { DbGetRecord }
procedure DbPutRecord;
{}
procedure WriteRec;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
FPos := DbGetHdrLen + ( pred(CurrentRec) * DbGetRecLen );
{$I-} seek(DBFAlias,FPos); {$I+}
if IOResult <> 0 then
DbSetError(1214) { Seek error putting record }
else
begin
blockwrite(DBFAlias,WrkSpc^[1],DbGetRecLen,DbVars.Actual);
if DbVars.Actual <> DbGetRecLen then
DbSetError(1166) { Write error putting record }
else
DbPutHeader(DBFAlias); {to update date modified}
end;
end;
end;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
if (IndexField <> 0)
and dbRecordIsActive(CurrentRec)
and dbIndexFieldChanged then {update the index}
begin
DeletingIndexEntry := true;
NdxDelKey(CurrentRec);
DeletingIndexEntry := false;
WriteRec;
NdxAddKey;
move(WrkSpc^[StrtPos(IndexField)],NdxSpc^,NdxFldLen);
end else
WriteRec;
end;
end; { PutRecord }
function DbSeqSearch( var RecNo: longint;
FieldNo: integer;
SearchTxt: String ): boolean;
{}
var L: longint;
TmpStr, TmpStr1: string;
I: integer;
begin
DbSeqSearch := false;
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
if DbGetNumRecs > 0 then
begin
SearchTxt := SetUpper(SearchTxt);
if RecNo = 0 then
RecNo := 1;
for L := RecNo to DbGetNumRecs do
begin
TmpStr := SetUpper(DbGetFldString(L,FieldNo));
if SearchTxt[0] <= TmpStr[0] then
begin
if ( pos(SearchTxt,TmpStr) <> 0 ) then
begin
DbSeqSearch := true;
RecNo := L;
exit;
end;
end;
end;
end;
end;
end; { DbSeqSearch }
function DbPackFile(FName: PathStr; IndexField: integer): integer;
{DBF must be closed}
var TF: file;
BufPtr: pointer;
Stat: byte;
PackHandle: integer;
HdrLen,
RecLen,
Counter: longint;
FilesClosed,
CloseBoth: boolean;
IFile: PathStr;
DFile: PathStr;
procedure CloseFiles;
begin
with DbVars.ActiveNode^.DBInfo do
begin
if not FilesClosed then
begin
{$I-} close(TF); {$I+}
if (IOResult = 0) then
begin
if CloseBoth then
DbCloseDataBase(PackHandle);
end
else
DbSetError(900); { close failure }
FilesClosed := true;
end;
end;
end; { CloseFiles }
function MoveHeader: integer;
{}
var L: integer;
begin
MoveHeader := 1;
with DbVars.ActiveNode^.DBInfo do
begin
HdrLen := DbGetHdrLen;
if GoldMaxAvail < HdrLen then
DBSetError(1009) { Insufficient heap available to move header }
else
begin
getmem(BufPtr,HdrLen);
seek(DBFAlias,0);
blockread(DBFAlias,BufPtr^,HdrLen,DbVars.Actual);
if DbVars.Actual <> HdrLen then
DbSetError(1109) { Unable to read dbf file while packing }
else
begin
blockwrite(TF,BufPtr^,HdrLen,DbVars.Actual);
if DbVars.Actual <> HdrLen then
DbSetError(1156) { Unable to write to temp file while packing }
else
MoveHeader := 0;
end;
freemem(BufPtr,HdrLen);
end;
{error}
end;
end; { MoveHeader }
function MoveRecords: integer;
{}
var L: integer;
begin
MoveRecords := 1;
with DbVars.ActiveNode^.DBInfo do
begin
Counter := 0;
for L := 1 to DbGetNumRecs do
begin
if DbRecordIsActive(L) then
begin
blockwrite(TF,WrkSpc^[1],RecLen,DbVars.Actual);
if DbVars.Actual <> RecLen then
DbSetError(1158) { Unable to write record while packing }
else
inc(Counter);
end;
end;
blockwrite(TF,EOFile,1,DbVars.Actual);
if DbVars.Actual <> 1 then
DbSetError(1159) { Unable to write EOF to Temp file while packing }
else
begin
DbPutNumRecs(Counter);
DbPutHeader(TF);
MoveRecords := 0;
end;
end;
end; { MoveRecords }
begin
DbPackFile := 1;
assign( TF, dbTempFname );
{$I-} rewrite( TF, 1 ); {$I+} { open temp file }
if IOResult <> 0 then
DbSetError(1301) { Error rewriting file in PackFile }
else
begin
IFile := SlashedDirectory(FileDirectory(FName))+FileName(FName)+IFX;
DFile := SlashedDirectory(FileDirectory(FName))+FileName(FName)+DFX;
if Exist(IFile) then
if DeleteFile(IFile) <> 0 then
DBSetError(1087); {Unable to delete index file}
PackHandle := DBOpenDataSet(DFile);
if PackHandle > 0 then
begin
CloseBoth := true;
if DbGetNumRecs < 1 then
DbSetError(1008) { No records Available }
else
begin
DbVars.Packing := true;
FilesClosed := false;
RecLen := DbGetRecLen;
if (MoveHeader = 0) and (MoveRecords = 0) then
begin
CloseFiles;
if (DeleteFile(DFile) = 0) then
if (RenameFile(dbTempFname,DFile) = 0) then
begin
PackHandle := DbOpenDataSet(DFile);
if PackHandle > 0 then
begin
DbPackFile := 0;
if (IndexField > 0) then
if NdxBuildNew(IndexField) <> 0 then
DbSetError(1085); { potential corruption }
DbCloseDataBase(PackHandle);
end;
end;
end;
end;
end;
end;
DbVars.Packing := false;
end; { DbPackFile }
{*************************************}
{** BEGIN .dbf file build methods **}
{*************************************}
function DbValidName( var Name: string ): boolean;
{}
var I, N, Len: integer;
begin
DbValidName := false;
if Name <> '' then
begin
Name := SetUpper(Name); { MUST be uppercase }
Len := length(Name);
if ( Len > 10 ) then
begin
Name[0] := chr(10);
Len := 10;
end;
if ( Name[1] in ['A'..'Z','_'] ) then
begin
N := 0;
for I := 2 to Len do
inc(N,ord( not (Name[I] in ['A'..'Z','0'..'9','_'] )));
if N = 0 then
begin
Name := PadLeft(Name,11,#0);
DbValidName := true;
end;
end;
end;
end; { DbValidName }
function DbValidType( var FldType: char ): boolean;
{}
begin
DbValidType := false;
FldType := UpCase(FldType);
with DbVars do
begin
if ( FldType IN [DbfCFld, DbfNFld, DbfLFld, DbfDFld, DbfMFld] ) then
begin
DbValidType := true;
with DbVars.ActiveNode^.DBInfo do
begin
if (not MemoIsIncluded) and (FldType = DbfMFld) then
begin
MemoIsIncluded := true;
HasMemo := true;
end;
end;
end;
end;
end; { DbValidType }
function DbValidFldLen( var FldLen: integer; FldType: char ): boolean;
{}
begin
with DbVars do
begin
if (( FldType = DbfCFld ) and ( FldLen in [1..254] ))
or (( FldType = DbfNFld ) and ( FldLen in [1..19] )) then
DbValidFldLen := true
else
if ( FldType = DbfLFld ) then { true or false - 0 or 1 }
begin
FldLen := 1;
DbValidFldLen := true;
end else
if ( FldType = DbfDFld ) then { date field = 8 YYYYMMDD }
begin
FldLen := 8;
DbValidFldLen := true;
end else
if ( FldType = DbfMFld ) then { memo = 10, index for dbt file }
begin
FldLen := 10;
DbValidFldLen := true;
end else
DbValidFldLen := false;
end;
end; { DbValidFldLen }
procedure DbValidateFldDecPl( var FldDecPl, FldLen:integer; FldType:char );
{}
begin
with DBVars do
begin
if ( FldType <> DbfNFld )
or ( FldDecPl < 0 )
or ( FldDecPl > 15 )
or ( FldLen < 3 ) then
FldDecPl := 0;
if ( FldDecPl > FldLen - 2) and (FldDecPL > 1) then
FldDecPl := FldLen - 2;
end;
end; { DbValidateFldDecPl }
function DbAddDbfField( FldName: string; FldType: char; FldLen, FldDecPl: integer ): integer;
{}
var FldArray: Array [1..32] of char;
AddResult: integer;
begin
if not DbVars.FldLstIsActive then
with DbVars do
begin
InitSLL(DbfFieldList);
FldLstIsActive := true;
end;
if DbVars.FldLstIsActive then
begin
with DbVars do
begin
DbAddDbfField := 0; { Success }
fillchar(FldArray,sizeof(FldArray),#0);
if ( DbfFieldList.TotalNodes > 127 ) then
DbSetError(1000) { too many fields }
else
if not DbValidName( FldName ) then { Field name validation }
DbSetError(1005)
else
if not DbValidType( FldType ) then { Field type validation }
DbSetError(1006)
else
if not DbValidFldLen( FldLen, FldType ) then { Field length validation }
DbSetError(1007)
else
begin
DbValidateFldDecPl( FldDecPl, FldLen, FldType ); { Field decimal place validation }
move(FldName[1],FldArray[1],11);
move(FldType,FldArray[12],1);
move(FldLen,FldArray[17],1);
move(FldDecPl,FldArray[18],1);
AddResult := _SLLAdd(DbfFieldList,FldArray,sizeof(FldArray));
if ( AddResult = 2 ) then
with DbfFieldList do
begin
_SLLDelNode(DbfFieldList,_SLLNodePtr(DbfFieldList,TotalNodes));
DbSetError(1024); { not enough memory }
DbAddDbfField := 7; { insufficient memory }
end;
end;
end;
end else
DbAddDbfField := 6;
end; { DbAddDbfField }
function DbBuildDataFile( FN: Pathstr; NdxFld : byte): integer;
{ Creates dbf file }
var TmpHandle: integer;
DF: file;
FldArray: array [1..32] of char;
TmpHead: HeaderInfo;
TmpField: FieldDesc;
vYear,vMth,vDay,vDow: word;
FLength: Byte;
FdType:Char;
function CreateFields: boolean;
{}
var I: integer;
begin
with DBVars do
begin
CreateFields := false;
fillchar(TmpHead.Reserved,sizeof(TmpHead.Reserved),0); { Clean reserved fields }
fillchar(FldArray,sizeof(FldArray),0);
TmpHead.RecLen := 0;
with DbfFieldList do
begin
if ( TotalNodes = 0 ) or ( not FldLstIsActive ) then
DbSetError(1086) { nothing to write }
else
begin
for I := 1 to TotalNodes do
begin
SLLGetNodeData(_SLLNodePtr(DbfFieldList,I),FldArray);
blockwrite(DF,FldArray[1],sizeof(FldArray),DbVars.Actual);
if (DbVars.Actual <> sizeof(FldArray)) then
begin
DbSetError(1151); { Write error creating header }
exit;
end;
inc(TmpHead.RecLen,integer(FldArray[17]));
if I = NdxFld then
begin
FLength := integer(FldArray[17]);
FDType := FldArray[12];
end;
end;
blockwrite(DF,EOH,1,DbVars.Actual); {End of hdr}
if (DbVars.Actual <> 1) then
DbSetError(1152) { Unable to write EOH creating DBF file }
else
begin
blockwrite(DF,EOFile,1,DbVars.Actual); {EndOfFile}
if (DbVars.Actual <> 1) then
DbSetError(1153) { Unable to write EOF creating DBF file }
else
CreateFields := true;
end;
end;
end;
end;
end; { CreateFields }
begin
if DBVars.FldLstIsActive then
with DbVars do
begin
DbBuildDataFile := 1; { set to error condition }
HasMemo := false;
{ validate file name then add dbf extension }
FN := FileName(FN) + DFX;
assign(DF,FN);
{$I-} rewrite(DF,1); {$I+} {Set record size to 1}
if IOResult <> 0 then
DbSetError(1039) { Unable to create DBF file }
else
begin
{$I-} seek(DF,32); {$I+} {Beginning of fields}
if IOResult <> 0 then
DbSetError(1201) { seek error creating DBF file }
else
if CreateFields then
begin
with DbVars do
begin
if HasMemo then
TmpHead.VersionNumber := $83
else
TmpHead.VersionNumber := $03;
getdate(vYear,vMth,vDay,vDow);
TmpHead.Update[1] := vYear-1900;
TmpHead.Update[2] := vMth;
TmpHead.Update[3] := vDay;
TmpHead.NbrRec := 0;
TmpHead.HdrLen := ( DbfFieldList.TotalNodes * 32 ) + 33;
TmpHead.RecLen := TmpHead.RecLen + 1; { single status byte }
end;
{$I-} seek(DF,0); {$I+} {Set to beginning of FILE}
if IOResult <> 0 then
DbSetError(1201) { seek error creating DBF file }
else
begin
blockwrite(DF,TmpHead,sizeof(TmpHead),DbVars.Actual);
if DbVars.Actual <> sizeof(TmpHead) then
DbSetError(1154) { Error writing header while creating DBF file }
else
begin
DbBuildDataFile := 0;
{$I-} close(DF); {$I+}
If IOResult <> 0 then
DbSetError(901); { close failure }
end;
if (NDXFld > 0) and (NDXFld < succ(DbfFieldList.TotalNodes)) then
begin
TmpHandle := DbOpenDataSet(FN);
if TmpHandle > 0 then
begin
if NdxBuildNew(NDXFld) = 0 then ;
if DbVars.HasMemo then
DbBuildMemoFile(FileName(FN)+MFX);
DbCloseDataBase(TmpHandle);
end;
end;
end;
FldLstIsActive := false;
DbVars.HasMemo := false; { reset }
_SLLDestroy(DbfFieldList);
DbVars.FldLstIsActive := false;
end;
end;
end;
end; { DbBuildDataFile }
{***********************************}
{** END .dbf file build methods **}
{***********************************}
procedure DbBuildMemoFile(FName:PathStr);
{}
var MemoHdrBlk: MemoDesc;
MemoFile: file;
begin
with MemoHdrBlk do
begin
NextMemoRec := 1;
fillchar(EmptySpace,sizeof(EmptySpace),#0);
assign(MemoFile,FName);
{$I-} rewrite(MemoFile,1); {$I+}
if IOResult <> 0 then
DbSetError(1033) { Error building new memo file }
else
begin
blockwrite(MemoFile,MemoHdrBlk,sizeof(MemoHdrBlk),DbVars.Actual);
if DbVars.Actual <> sizeof(MemoHdrBlk) then
DbSetError(1155); { Write error during memo file creation }
{$I-} close(MemoFile); {$I+}
if IOResult <> 0 then
DbSetError(902); {close failure}
end;
end;
end; { DBBuildMemoFile }
function DbRebuildMemo(FName: PathStr): integer;
{}
var I,J: longint;
Handle: integer;
MemoD: MemoCfg;
MemoL: SingleLL;
MemoRec: longint;
TempMemoFile: File;
NxtMemoRec,LstMemoRec: longint;
begin
DbRebuildMemo := 1;
Handle := DbOpenDataSet(FName);
if Handle = 0 then
DbSetError(1019) {Cannot activate database; closed or inactive handle}
else
begin
with DbVars.ActiveNode^.DBInfo do
begin
if MemoIsIncluded then
begin
DbBuildMemoFile(DbTempFName);
{now open the file}
assign(TempMemoFile,FName);
{$I-} reset(TempMemoFile,1); {$I+}
if IoResult <> 0 then
begin
DbSetError(1301); { Error in temp memo file }
exit;
end;
NxtMemoRec := 1;
LstMemoRec := 0;
InitSLL(MemoL);
MemoAssignSLL(MemoD,MemoL);
for I := 1 to DbGetNumRecs do
if DbRecordIsActive(I) then
for J := 1 to DbTotalFields do
begin
if DbGetFldType(J) = DbVars.DbfMFld then
begin
DbGetFldMemo(I,J,MemoD);
if DbSetFldMemoEngine(J,MemoL,DBTAlias,NxtMemoRec,LstMemoRec) <> 0 then
DbSetError(1088); {Error rebuilding memo file}
end;
end;
{ close memo files and rename }
{!!!!}
DbReBuildMemo := 0;
end
else
DbSetError(1023);
end;
end;
end; { RebuildMemo }
{*************************}
{** End of Memo Stuff **}
{*************************}
procedure SetToPrevNode( Node: DBListNodePtr );
{}
var TempNode1, TempNode2: DBListNodePtr;
begin
if Node <> nil then
with DbVars do
begin
TempNode1 := StartNode;
if Node <> StartNode then
begin
while TempNode1^.NextPtr <> Node do
begin
TempNode2 := TempNode1^.NextPtr;
TempNode1 := TempNode2;
end;
end;
DbVars.ActiveNode := TempNode1;
end;
end; { SetToPrevNode }
procedure DbCloseDataBase( Handle: integer );
{}
begin
if (Handle > 0) and (Handle < succ(DbVars.DBsOpen)) then
begin
DbSetActiveDatabase(Handle);
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
freemem(WrkSpc,DbGetRecLen);
WrkSpc := nil;
if NdxSpc <> nil then
begin
freemem(NdxSpc,NdxFldLen);
NdxSpc := nil;
freemem(bakNdxSpc,NdxFldLen);
BakNdxSpc := nil;
end;
with DbVars.ActiveNode^.DBInfo do
begin
if DFOpen then
begin
DFOpen := false;
{$I-} close(DBFAlias); {$I+}
if (IOResult <> 0) then
DbSetError(903); {close failure}
end;
if indexField > 0 then
begin
indexField := 0;
ReleaseAllPages(NDXName);
{$I-} close(NDXAlias); {$I+}
if (IOResult <> 0) then
DbSetError(904); {close failure}
end;
end;
freeMem(pField,sizeof(pField^));
freeMem(pHead,sizeof(pHead^));
_SLLDestroy(FldInfo);
if MemoIsIncluded then
freemem(pMemo,sizeof(pMemo^));
if not DbVars.ClosingAll and ( Handle = DbVars.DBsOpen ) then
begin
while not DbVars.ActiveNode^.DBInfo.DFOpen and
( DbVars.DBsOpen > 0 ) do
begin
freemem(DbVars.ActiveNode,sizeof(DbVars.ActiveNode^));
if DbVars.ActiveNode <> DbVars.StartNode then
begin
SetToPrevNode(DbVars.ActiveNode);
DbVars.ActiveNode^.NextPtr := nil;
end;
dec(DbVars.DBsOpen);
end;
if DbVars.DBsOpen = 0 then
begin
DbVars.StartNode := nil;
DbVars.ActiveNode := nil;
end;
end;
end;
end;
end; { DbCloseDataBase }
procedure DbCloseAllDatabases;
{}
var Temp1,Temp2: DBListNodePtr;
Count: integer;
begin
with DbVars do
begin
if DBsOpen > 0 then
begin
ClosingAll := true;
Count := 1;
Temp1 := StartNode;
while Temp1 <> nil do
begin
Temp2 := Temp1^.NextPtr;
if Temp1^.DBInfo.DFOpen then
DbCloseDatabase(Count);
inc(Count);
freemem(Temp1,sizeof(Temp1^));
Temp1 := Temp2;
end;
ClosingAll := false;
end;
StartNode := nil;
ActiveNode := nil;
end;
end; { DbCloseAllDatabases }
function DbReadStructure: integer;
{}
var I: integer;
HdrTerminator: byte;
begin
DbReadStructure := 1; { failure }
with DbVars.ActiveNode^.DBInfo do
begin
{$I-} seek(DBFAlias,0); {$I+} { Move ptr to TOF }
if IOResult <> 0 then
DbSetError(1202) { seek error }
else
begin
{ read header }
blockread(DBFAlias, pHead^, sizeof(pHead^), DbVars.Actual);
if DbVars.Actual <> sizeof(pHead^) then
DbSetError(1102) { read error }
else
begin
if ((pHead^.VersionNumber AND 7) <> $03) then
DBSetError(1010) { Not a valid dBase File, may be corrupt }
else
begin
if (pHead^.VersionNumber = $83) then
begin
MemoIsIncluded := true;
getmem(pMemo,sizeof(pMemo^));
end;
if ( DbTotalFields > 0 ) then
begin
InitSLL(FldInfo);
for I := 1 to DbTotalFields do
begin
blockread(DBFAlias,pField^,sizeof(pField^),DbVars.Actual);
if DbVars.Actual <> sizeof(pField^) then
DbSetError(1103) { Unable to read field info while readinf structure }
else if (_SLLAdd(FldInfo,pField^,sizeof(pField^)) <> 0) then
DbSetError(1025); { error creating field list }
end;
end;
{ Last Header Byte }
blockread(DBFAlias,HdrTerminator,1,DbVars.Actual);
if DbVars.Actual <> 1 then
DbSetError(1104) { Unable to read header terminator }
else if HdrTerminator <> EOH then
DBSetError(1010) {File may be corrupted}
else
DbReadStructure := 0; {Structure OK}
end;
end;
end;
end;
end; { DbReadStructure }
function DbOpenDataFile(DBFile: PathStr): integer;
{internal use only - Use DbOpenDataSet externally}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
DbOpenDataFile := 1; { failure }
if not Exist(DBFile) then
DBSetError(1021) { File not found }
else
begin
assign(DBFAlias, DBFile);
{$I-} reset(DBFAlias,1); {$I+} { Set record length to 1 }
DFOpen := (IOResult = 0);
if not DFOpen then
DbSetError(1201) { Unable to open dbf file during OpenDataFile }
else
DbOpenDataFile := 0; { success }
end;
end;
end; { DbOpenDataFile }
procedure DbOpenIndexFile;
{internal use only - Use DbOpenDataSet externally}
var ECode: integer;
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103)
else
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
if not Exist(NDXName) then
IndexField := 0
else
begin
assign(NDXAlias, NDXName);
{$I-} reset(NDXAlias,PAGESIZE);
ECode := IOResult; {$I+}
if ECode <> 0 then
DbSetError(1251) { Unable to reset index while opening }
else
begin
IndexField := GetIndexedField(NDXName,NDXAlias);
NdxFldLen := DbGetFldLength(IndexField);
IndexUpperCase := GetUpperCaseFlag(NdxName,NdxAlias);
InitializeFindRecord; { ensure Find Problems don't occur }
if Ecode <> 0 then
Ecode := 2000
else if NdxValidate(true) <> 0 then
Ecode := 2001;
{ this doesn't need to be called if ECode is 0 ??????}
DBSetError(Ecode);
if (Ecode = 0) and (NdxSpc = nil) then
AllocateNdxSpc;
end;
end;
end;
end; { DbOpenIndexFile }
function DbOpenMemoFile: integer;
{internal use only - Use DbOpenDataSet externally}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
DbOpenMemoFile := 1; { failure }
if not Exist(DBTName) then
DbBuildMemoFile(DBTName);
assign(DBTAlias,DBTName);
{$I-} reset(DBTAlias,1); {$I+}
if IOResult <> 0 then
DbSetError(1036) { Error reseting dbt file to access memo }
else
with DbVars.ActiveNode^.DBInfo.pMemo^ do
begin
blockread(DBTAlias,NextMemoRec,sizeof(NextMemoRec),DbVars.Actual);
if DbVars.Actual <> sizeof(NextMemoRec) then
DbSetError(1087) {}
else
begin
if (FileSize(DbtAlias) div MemoPageSize) = pred(NextMemoRec) then
begin
LastMemoRec := pred(NextMemoRec);
DbOpenMemoFile := 0;
end else
DbSetError(1035); { DBT corrupt }
end;
{$I-} close(DBTAlias); {$I+}
if (IOResult <> 0) then
DbSetError(905); {close failure}
end;
end;
end; { DbOpenMemoFile }
procedure SetFileNames(DBFile: pathstr);
{requirement of this unit}
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
DBPath := SlashedDirectory(FIleDirectory(DBFile)); {extract pathname}
DBFile := FileName(DBFile); {extract filename}
DBFName := DBFile+ DFX; {make DBF, IDX, and MFX file names the same}
NDXName := DBFile+ IFX;
DBTName := DBFile+ MFX;
end;
end; { SetFileNames }
function DbOpenDataSet( DBFile: pathstr ): integer;
{ DbOpenDataSet returns the Handle of the database set (positive values)
or 0 (zero) if the database failed to open. Error codes may be found
in DbLastError.
}
var
TmpFieldName: string[11];
Handle: integer;
begin
Handle := DbInitDatabase; {returns unique handle}
if Handle = 0 then
DbOpenDataSet := 0
else
begin
{$IFDEF CHECK}
if DBVARS.ActiveNode = nil then
DbSetError(103);
{$ENDIF}
with DbVars.ActiveNode^.DBInfo do
begin
SetFileNames(DBFile);
{Open files}
if ( DbOpenDataFile(DBPath + DBFName) = 0) and (DbReadStructure = 0) then
begin
DbOpenDataSet := Handle;
getmem(WrkSpc,DbGetRecLen);
{ serves no purpose, just a bit of clean up }
fillchar(pHead^.Reserved,sizeof(pHead^.Reserved),#0);
fillchar(pField^.Reserved1,sizeof(pField^.Reserved1),#0);
fillchar(pField^.Reserved2,sizeof(pField^.Reserved2),#0);
DbOpenIndexFile;
if MemoIsIncluded then
MFOpen := DbOpenMemoFile = 0;
end
else
DbOpenDataSet := 0;
end;
end;
end; { DbOpenDataSet }
procedure SetShowNdxProgress(Proc: ShowNdxProgressProc);
{}
begin
DbVars.ShowNdxProgress := Proc;
end;
{*********************************************}
{** U N I T I N I T I A L I Z A T I O N **}
{*********************************************}
procedure DbDefaultSettings;
{}
begin
with DbVars do
begin
DbfCFld := 'C'; { Character field }
DbfNFld := 'N'; { Numeric field }
DbfLFld := 'L'; { Logical field }
DbfDFld := 'D'; { Date field }
DbfMFld := 'M'; { Memo field }
FullStrings := false;
ShowNdxProgress := NoProgressHook;
end;
end; { DbDefaultSettings }
procedure GoldDBInit;
{}
begin
with DbVars do
begin
Packing := false;
FldLstIsActive := false;
ClosingAll := false;
HasMemo := false;
StartNode := nil;
ActiveNode := nil;
DBsOpen := 0;
LastECode := 0;
EMsgFunc := DbEMsg;
Actual := 0;
end;
DbDefaultSettings;
NdxInit;
end; {GoldDBInit}
begin
GoldDBInit;
end.